package hnapay

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"crypto/md5"
	"encoding/base64"
	"github.com/pkg/errors"
	"github.com/astaxie/beego"
)

type Auth struct {
	requrl    string
	merCode   string
	appsecret string
}

type MsgHead struct {
	SerCode    string   `json:"serCode"`
	MerCode    string   `json:"merCode"`
	OrderId    string   `json:"orderId"`
	MerDate    string   `json:"merDate"`
	MerTime    string   `json:"merTime"`
	VersionNo  string   `json:"versionNo"`
	SignType   string   `json:"signType"`
}

func NewSDK(restURL,merCode,appsecret string) *Auth {
	return &Auth{requrl:restURL,merCode:merCode,appsecret:appsecret}
}

func (this *Auth) Request(msg string,response interface{}) (respMap map[string]interface{}, err error) {
	v := make(url.Values)
	v.Set("msg", msg)
	//beego.Debug("hnapay req:", msg)
	resp, e := http.PostForm(this.requrl, v)
	if e != nil {
		err = e
	}
	defer resp.Body.Close()
	bodyBytes, e := ioutil.ReadAll(resp.Body)
	if e != nil {
		err = e
		return
	}
	//beego.Debug("hnapay rsp:", string(bodyBytes))
	var result struct {
		Error  string `json:"error"`
		ErrMsg string `json:"errMsg"`
		Msg    string `json:"msg"`
	}
	err = json.Unmarshal(bodyBytes, &result)
	if err != nil {
		err = errors.New(fmt.Sprintf("%s %s", err.Error(), string(bodyBytes)))
		return
	}
	if result.Error != "0000" {
	   err = errors.New(fmt.Sprintf("%s", result.ErrMsg))
	   return
	}
	decodeByte, e := base64Decode(result.Msg)
	if e != nil {
		err = e
		return
	}
	//beego.Debug("hnapay rsp decodeByte:", string(decodeByte))
	err = json.Unmarshal(decodeByte, &response)
	if err != nil {
		err = errors.New(fmt.Sprintf("%s %s", err.Error(), string(decodeByte)))
		return
	}
	return
}

func (this *Auth) RefundRequest(msg string,response interface{}) (respMap map[string]interface{}, err error) {
	v := make(url.Values)
	v.Set("msg", msg)
	//beego.Debug("RefundRequest req:", msg)
	resp, e := http.PostForm(this.requrl, v)
	if e != nil {
		err = e
	}
	defer resp.Body.Close()
	bodyBytes, e := ioutil.ReadAll(resp.Body)
	if e != nil {
		err = e
		return
	}
	//beego.Debug("RefundRequest rsp:", string(bodyBytes))
	var result struct {
		Error  string `json:"error"`
		ErrMsg string `json:"errMsg"`
		Msg    string `json:"msg"`
	}
	err = json.Unmarshal(bodyBytes, &result)
	if err != nil {
		err = errors.New(fmt.Sprintf("%s %s", err.Error(), string(bodyBytes)))
		return
	}
	if result.Error != "0001" {
	   err = errors.New(fmt.Sprintf("%s", result.ErrMsg))
	   return
	}
	decodeByte, e := base64Decode(result.Msg)
	if e != nil {
		err = e
		return
	}
	beego.Debug("RefundRequest rsp decodeByte:", string(decodeByte))
	err = json.Unmarshal(decodeByte, &response)
	if err != nil {
		err = errors.New(fmt.Sprintf("%s %s", err.Error(), string(decodeByte)))
		return
	}
	return
}

func signMd5(headcontent, publicKey string) string {
    headcontent1 := fmt.Sprintf("%x", md5.Sum([]byte(headcontent)))
	headcontent2 := headcontent1 + publicKey
	sign := fmt.Sprintf("%x", md5.Sum([]byte(headcontent2)))
    return sign
}

func base64Encode(data []byte) string {
	return base64.StdEncoding.EncodeToString(data)
}

func base64Decode(data string) ([]byte, error) {
	return base64.StdEncoding.DecodeString(data)
}


